#include "stdafx.h"

#include "TEST.h"

TextBox::TextBox(int left, int top, int width, int height)
{
	this->left = left;
	this->top = top;
	this->width = width;
	this->height = height;

	determine_valid_region();
	update_graphical();

	cursor_length = fontsize + 5;
}

TextBox::~TextBox()
{
}

void TextBox::draw(Gdiplus::Graphics & graphics)
{
	//draw background
	graphics.FillRectangle(brush_back, left, top, width, height);
	//draw border
	switch (state)
	{
	case STATE_NORMAL:
		graphics.DrawRectangle(pen_border_normal, left, top, width, height);
		break;
	case STATE_MOVE:
		graphics.DrawRectangle(pen_border_move, left, top, width, height);
		break;
	case STATE_DOWN:
		graphics.DrawRectangle(pen_border_down, left, top, width, height);
		break;
	}
	//draw text
	Gdiplus::RectF temp = { 0,0,0,0 };
	Gdiplus::PointF origin = { 0,0 };
	int display_length = 0;
	while (string_pos + display_length < text.length() && temp.Width < width - 2 * TEXT_OFFSET)
	{
		display_length++;
		graphics.MeasureString(text.c_str() + string_pos, display_length, font, origin, &temp);
	}
	origin.X = TEXT_OFFSET + left - 2;											//there is a -2 because of unknown problems
	origin.Y = (height - temp.Height) / 2 + top;
	graphics.DrawString(text.c_str() + string_pos, display_length, font, origin, brush_text);
	//draw cursor
	if (focused)
	{
		
		graphics.MeasureString(text.c_str() + string_pos, cursor_pos, font, origin, &temp);
		int cx = left + TEXT_OFFSET + temp.Width + 1;
		int cy = top + height / 2;
		graphics.DrawLine(pen_cursor, cx, cy - cursor_length / 2, cx, cy + cursor_length / 2);
	}
}

void TextBox::update_graphical()
{
	if (brush_back)
	{
		delete brush_back;
	}
	if (pen_border_down)
	{
		delete pen_border_down;
	}
	if (pen_border_normal)
	{
		delete pen_border_normal;
	}
	if (pen_border_move)
	{
		delete pen_border_move;
	}
	if (brush_text)
	{
		delete brush_text;
	}
	if (pen_cursor)
	{
		delete pen_cursor;
	}
	if (ffm)
	{
		delete ffm;
	}
	if (font)
	{
		delete font;
	}

	brush_back = new Gdiplus::SolidBrush(color_back);
	pen_border_down = new Gdiplus::Pen(color_border_down, BORDER_WIDTH);
	pen_border_normal = new Gdiplus::Pen(color_border_normal, BORDER_WIDTH);
	pen_border_move = new Gdiplus::Pen(color_border_move, BORDER_WIDTH);
	brush_text = new Gdiplus::SolidBrush(color_text);
	pen_cursor = new Gdiplus::Pen(color_cursor, CURSOR_WIDTH);

	ffm = new Gdiplus::FontFamily(fontname.c_str());
	font = new Gdiplus::Font(ffm, fontsize);
}

void TextBox::set_color_back(Gdiplus::Color color)
{
	color_back = color;
	update_graphical();
}

void TextBox::set_color_border_down(Gdiplus::Color color)
{
	color_border_down = color;
	update_graphical();
}

void TextBox::set_color_border_move(Gdiplus::Color color)
{
	color_border_move = color;
	update_graphical();
}

void TextBox::set_color_border_normal(Gdiplus::Color color)
{
	color_border_normal = color;
	update_graphical();
}

void TextBox::set_fontname(std::wstring name)
{
	fontname = name;
	update_graphical();
}

void TextBox::set_fontsize(int size)
{
	fontsize = size;
	update_graphical();
}

void TextBox::determine_valid_region()
{
	valid_region = new RectShape(left, top, width, height);
}

bool TextBox::LButtonDown(int x, int y)
{
	state = STATE_DOWN;

	left_button_down(x, y);
	return true;
}

bool TextBox::MouseMove(int button, int x, int y)
{
	if (state == STATE_NORMAL && button == MOUSE_NONE)
	{
		state = STATE_MOVE;
	}

	mouse_move(button, x, y);
	return true;
}

bool TextBox::MouseLeave(int button, int x, int y)
{
	if (!focused)
	{
		state = STATE_NORMAL;
	}

	mouse_leave(button, x, y);
	return true;
}

bool TextBox::KeyUp(int keycode)
{
	text.push_back(MapVirtualKey(keycode, MAPVK_VK_TO_CHAR));
	cursor_pos++;

	key_up(keycode);
	return true;
}

bool TextBox::LostFocus()
{
	state = STATE_NORMAL;

	lost_focus();
	return true;
}